home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir24
/
psi110g.zip
/
INDEX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-05
|
29KB
|
1,110 lines
/* Mail Index File routines for JNOS and others.
* (C) 1993, Johan. K. Reinalda, WG7J/PA3DIS
* Free for non-commercial use if this notice is retained.
*
* You should be able to patch this into you mailer program easily.
* There are two public functions.
*
* int MsgsInMbx(char *name);
* this routine returns the number of messages in a mailbox.
*
* Calling convention:
* 'char *name' is the name of the mailbox, in 'directory format'.
* this means that subdirectories should be represented by '/'
* characters, and not '.' or '\' . Also, the '.txt' extension
* should not be used !
*
* Return value:
* It will return -1 if it detects an error in the index file.
* Otherwise the number of messages will be returned.
*
* Use:
* JNOS uses it to dynamically size the structure that tracks messages.
*
* int IndexFile(char *name,int verbose);
* This routines creates an index file for the mailbox given.
*
* Calling convention:
* 'char *name'
* 'char *name' is the name of the mailbox, in 'directory format'.
* this means that subdirectories should be represented by '/'
* characters, and not '.' or '\' . Also, the '.txt' extension
* should not be used ! The 'mailspool' directory will be pre-pended,
* and should not be included in the mailbox name. Eg. the file
* '/spool/mail/users/johan.txt' should be indexed as 'users/johan'
*
* 'int verbose'
* if set, the index will be printed before it is written.
*
* Return values:
* 0 if no error occured
* -2 if it can not open the mailbox for reading binary mode
* -3 if it can not open the index file for writing
* -10 on other errors
*
* Notes:
* -you should make sure the mailbox file is properly locked before
* calling this routine.
*
* -you need to provide the following variables:
* char *Mailspool, should be "/spool/mail"
* char *Arealist, should be "/spool/areas"
*
* -you also need to provide a dummy function pwait() in your sources,
* to avoid getting an unknown function error when linking.
* void pwait(void *p) {};
* should do it...
*/
#ifdef MSDOS
#include <io.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
#ifdef MSDOS
#include <dir.h>
#include <dos.h>
#endif
#include "global.h"
#include "socket.h"
#include "index.h"
#include "mailutil.h"
#include "mailbox.h"
#include "smtp.h"
#include "files.h"
#include "bm.h"
#ifdef MAIL2IND
#undef fopen
#define tprintf printf
#define tputc putchar
#endif
/* return the number of messages in a given mailbox.
* name needs to be in directory format.
* Returns:
* -1 if index file is corrupt,
* otherwize the number of messages in the mailbox
*/
int MsgsInMbx(char *name) {
int ind;
struct indexhdr hdr;
char buf[FILE_PATH_SIZE];
sprintf(buf,"%s/%s.ind",Mailspool,name);
if((ind = open(buf,READBINARY)) == -1)
return 0;
/* Read the header */
if(read_header(ind,&hdr) == -1)
hdr.msgs = 0;
close(ind);
return hdr.msgs;
}
/* replace terminating end of line marker(s) with null */
void
rip(s)
register char *s;
{
register char *cp;
if((cp = strchr(s,'\n')) != NULLCHAR)
*cp = '\0';
}
char *skipwhite(char *cp) {
while((*cp != '\0') && (*cp == ' ' || *cp == '\t'))
cp++;
return cp;
}
/* Given a string of the form <user@host>, extract the part inside the
* angle brackets and return a pointer to it.
*/
char *
getname(cp)
char *cp;
{
char *cp1;
if ((cp = strchr(cp,'<')) == NULLCHAR)
return NULLCHAR;
cp++; /* cp -> first char of name */
cp = skipwhite(cp);
if((cp1 = strchr(cp,'>')) == NULLCHAR)
return NULLCHAR;
*cp1 = '\0';
return cp;
}
/* Parse a string in the "Text: Text <user@host>" or "Text: user@host (Text)"
* formats for the address user@host.
*/
char *
getaddress(string,cont)
char *string;
int cont; /* true if string is a continued header line */
{
char *cp, *ap = NULLCHAR;
int par = 0;
if((cp = getname(string)) != NULLCHAR) /* Look for <> style address */
return cp;
cp = string;
if(!cont)
if((cp = strchr(string,':')) == NULLCHAR) /* Skip the token */
return NULLCHAR;
else
++cp;
for(; *cp != '\0'; ++cp) {
if(par && *cp == ')') {
--par;
continue;
}
if(*cp == '(') /* Ignore text within parenthesis */
++par;
if(par)
continue;
if(*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == ',') {
if(ap != NULLCHAR)
break;
continue;
}
if(ap == NULLCHAR)
ap = cp;
}
*cp = '\0';
return ap;
}
char *Months[12] = { "Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec" };
char *Hdrs[] = {
"Approved: ",
"From: ",
"To: ",
"Date: ",
"Message-Id: ",
"Subject: ",
"Received: ",
"Sender: ",
"Reply-To: ",
"Status: ",
"X-BBS-Msg-Type: ",
"X-Forwarded-To: ",
"Cc: ",
"Return-Receipt-To: ",
"Apparently-To: ",
"Errors-To: ",
"Organization: ",
"Newsgroups: ",
"Path: ",
"X-BBS-Hold: ",
NULLCHAR,
};
/* return the header type */
int
htype(s)
char *s;
{
register char *p;
register int i;
p = s;
/* check to see if there is a ':' before and white space */
while (*p != '\0' && *p != ' ' && *p != ':')
p++;
if (*p != ':')
return NOHEADER;
for (i = 0; Hdrs[i] != NULLCHAR; i++) {
if (strnicmp(Hdrs[i],s,strlen(Hdrs[i])) == 0)
return i;
}
return UNKNOWN;
}
int get_index(int msg,char *name,struct mailindex *ind) {
int idx;
struct indexhdr hdr;
char buf[FILE_PATH_SIZE];
sprintf(buf,"%s/%s.ind",Mailspool,name);
if((idx=open(buf,READBINARY)) == -1) {
return -1;
}
if((read_header(idx,&hdr) == 0) && (msg <= hdr.msgs)) {
while(msg--) {
default_index(name,ind);
read_index(idx,ind);
}
close(idx);
return 0;
}
close(idx);
return -1;
}
void set_index(char *buf,struct mailindex *index) {
char *s,*cp;
struct cclist *cc;
struct fwdbbs *bbs;
struct tm t;
switch(htype(buf)) {
case APPARTO:
if(index->to)
break;
/* Notice fall-through */
case TO:
free(index->to);
index->to = strdup(getaddress(buf,0));
break;
case STATUS:
if(buf[8] == 'R')
index->status |= BM_READ;
break;
case XBBSHOLD:
index->status |= BM_HOLD;
break;
case FROM:
free(index->from);
index->from = strdup(getaddress(buf,0));
break;
case REPLYTO:
free(index->replyto);
index->replyto = strdup(getaddress(buf,0));
break;
case SUBJECT:
free(index->subject);
index->subject = strdup(&buf[9]);
/* translate possible left over cr/lf's to spaces */
cp = index->subject;
while(*cp) {
if(*cp == '\n' || *cp == 0xd){
*cp = '\0';
break;
}
cp++;
}
break;
case BBSTYPE:
index->type = buf[16];
break;
case MSGID:
free(index->messageid);
index->messageid = strdup(getaddress(buf,0));
break;
case XFORWARD:
bbs = mallocw(sizeof(struct fwdbbs));
strcpy(bbs->call,&buf[16]);
bbs->next = index->bbslist;
index->bbslist = bbs;
break;
case CC:
s = &buf[4];
while(*s) {
if((cp=strchr(s,','))!=NULL){
*cp = '\0';
} else
cp = s + strlen(s) - 1;
while(*s == ' ' || *s == '\t')
s++;
cc = mallocw(sizeof(struct cclist));
cc->to = strdup(s);
cc->next = index->cclist;
index->cclist = cc;
s = cp + 1;
}
break;
case DATE:
/* find age from ARPA style date */
index->date = mydate(&buf[6]);
break;
} /* switch */
}
/* Update the index file */
int WriteIndex(int idx, struct mailindex *ind) {
long startoffset,length;
int len, xlen;
struct indexhdr hdr;
struct fwdbbs *bbs;
struct cclist *cc;
char null = '\0';
if ((startoffset = lseek(idx,0,SEEK_CUR)) == -1L) return -1;
/* write length bytes */
write(idx,&len,sizeof(len));
/* write message id */
write(idx,&ind->msgid,sizeof(ind->msgid));
xlen = sizeof(ind->msgid);
/* write message type */
write(idx,&ind->type,sizeof(ind->type));
xlen += sizeof(ind->type);
/* write message status */
write(idx,&ind->status,sizeof(ind->status));
xlen += sizeof(ind->status);
/* write message size */
write(idx,&ind->size,sizeof(ind->size));
xlen += sizeof(ind->size);
/* write to-address */
if(ind->to) {
write(idx,ind->to,strlen(ind->to));
xlen += strlen(ind->to);
}
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* write from-address */
if(ind->from){
write(idx,ind->from,strlen(ind->from));
xlen += strlen(ind->from);
}
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* write subject field */
if(ind->subject){
write(idx,ind->subject,strlen(ind->subject));
xlen += strlen(ind->subject);
}
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* write reply-to field */
if(ind->replyto){
write(idx,ind->replyto,strlen(ind->replyto));
xlen += strlen(ind->replyto);
}
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* write message-id field */
if(ind->messageid){
write(idx,ind->messageid,strlen(ind->messageid));
xlen += strlen(ind->messageid);
}
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* write received date */
write(idx,&ind->mydate,sizeof(ind->mydate));
xlen += sizeof(ind->mydate);
/* write date */
write(idx,&ind->date,sizeof(ind->date));
xlen += sizeof(ind->date);
/* write all Cc addressees */
for(cc=ind->cclist;cc;cc=cc->next){
write(idx,cc->to,strlen(cc->to)+1);
xlen += strlen(cc->to)+1;
}
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* write all forwarded bbs's */
for(bbs=ind->bbslist;bbs;bbs = bbs->next){
write(idx,bbs->call,strlen(bbs->call)+1);
xlen += strlen(bbs->call)+1;
}
/* terminate with null character */
write(idx,&null,sizeof(null));
xlen += sizeof(null);
/* Now update the length */
len = (int) (lseek(idx,0,SEEK_CUR) - startoffset - sizeof(len));
lseek(idx,startoffset,SEEK_SET); /* regain start pos */
if (len != xlen) { /* serious write or seek error */
write(idx, &null, 0); /* truncate index */
return -1;
}
if (write(idx,&len,sizeof(len)) != sizeof(len)) return -1;
/* Now update the number of records */
if (read_header(idx,&hdr) == 0) {
hdr.msgs++;
if(!(ind->status & BM_HOLD+BM_READ))
hdr.unread++;
xlen=write_header(idx,&hdr);
}
else xlen = -1;
/* Go to end of file again */
lseek(idx,0,SEEK_END);
return xlen;
}
void default_header(struct indexhdr *hdr) {
hdr->msgs = 0;
hdr->unread = 0;
}
void default_index(char *name, struct mailindex *ind) {
struct fwdbbs *cbbs,*nbbs;
struct cclist *cc,*ncc;
ind->msgid = 0;
#ifdef MAILCMDS
#ifdef MAILBOX
if(isarea(name))
ind->type = 'B';
else
#endif
#endif
ind->type = 'P';
ind->status = 0;
ind->size = 0;
free(ind->to);
ind->to = NULL;
free(ind->from);
ind->from = NULL;
free(ind->subject);
ind->subject = NULL;
free(ind->replyto);
ind->replyto = NULL;
free(ind->messageid);
ind->messageid = NULL;
ind->mydate = 0;
ind->date = 0;
for(cbbs = ind->bbslist;cbbs;cbbs = nbbs) {
nbbs = cbbs->next;
free(cbbs);
}
ind->bbslist = NULL;
for(cc = ind->cclist;cc;cc = ncc) {
ncc = cc->next;
free(cc->to);
free(cc);
}
ind->cclist = NULL;
}
long mydate(char *s) {
struct tm t;
char *cp;
while(*s == ' ')
s++;
/* check to see if there is a "Day, " field */
if((cp=strchr(s,',')) != NULL) {
/* probably standard ARPA style header */
cp += 2; /* get past header and DAY field */
} else {
/* probably a NNTP style message, that has no
* "Day, " part in the date line
*/
cp = s;
}
while(*cp == ' ')
cp++;
/* now we should be at the start of the
* "14 Apr 92 08:14:32" string
*/
if(strlen(cp) < 17)
return 0;
t.tm_mday = atoi(cp);
/* Find month */
while(*cp != ' ')
++cp;
while(*cp == ' ')
++cp;
for(t.tm_mon=0; t.tm_mon < 12; t.tm_mon++)
if(strnicmp(Months[t.tm_mon],cp,3) == 0)
break;
if(t.tm_mon == 12)
return 0; /* invalid */
t.tm_year = atoi(cp+4);
/* Modification by VE4WTS for 4-character year string */
if(t.tm_year>100) {
t.tm_year=t.tm_year%100;
t.tm_hour=atoi(cp+9);
t.tm_min=atoi(cp+12);
t.tm_sec=atoi(cp+15);
} else {
t.tm_hour = atoi(cp+7);
t.tm_min = atoi(cp+10);
t.tm_sec = atoi(cp+13);
}
/*
tprintf("DATE: %d %d %d, %d %d %d\n",
t.tm_mday,t.tm_mon,t.tm_year,t.tm_hour,t.tm_min,t.tm_sec);
*/
return mktime(&t);
}
/* Read a file containing messages,
* and build the index file from scratch from the smtp headers.
* Parameters:
* char *name should be the full area filename in dir format,
* without ending '.txt' ! Eg: '/spool/mail/johan'
* int verbose ; if set, the index is printed before written
*/
int IndexFile(char *name,int verbose) {
FILE *fp;
int header,previous;
long start,pos;
char *cp;
int idx;
struct indexhdr hdr;
struct mailindex ind;
char buf[FILE_PATH_SIZE];
sprintf(buf,"%s/%s.txt",Mailspool,name);
if((fp = fopen(buf,READ_BINARY)) == NULL)
return NOMBX;
/* Create new index file */
sprintf(buf,"%s/%s.ind",Mailspool,name);
if((idx = open(buf,CREATETRUNCATEBINARY,CREATEMODE)) == -1) {
fclose(fp);
return NOIND;
}
/* set number of msgs to 0 */
default_header(&hdr);
if (write_header(idx,&hdr) == -1) return ERROR;
start = pos = 0;
previous = 0;
memset(&ind,0,sizeof(ind));
default_index(name,&ind);
while(bgets(buf, sizeof(buf), fp) != NULL) {
pwait(NULL); /* Be nice to others :-) */
/* search 'From ' line */
if(!strncmp(buf,"From ",5)) {
/* Start of next message */
if(previous) {
/* Write index for previous message */
ind.size = pos - start;
if(verbose)
print_index(&ind);
if(WriteIndex(idx,&ind) == -1) {
default_index("",&ind);
fclose(fp);
close(idx);
return ERROR;
}
} else
previous = 1;
/* Clear the index for this message */
default_index(name,&ind);
start = pos;
/* Read the 'Received...' and 'ID... lines'
* to get the msgid - WG7J
*/
if(bgets(buf, sizeof(buf), fp) == NULL) { /* "Received " line */
default_index("",&ind);
fclose(fp);
close(idx);
return ERROR;
}
if(bgets(buf, sizeof(buf), fp) == NULL) { /* 'id' line */
default_index("",&ind);
fclose(fp);
close(idx);
return ERROR;
}
if((cp=strstr(buf,"AA")) != NULL)
/* what follows is the message-number */
ind.msgid = atol(cp+2);
if((cp=strchr(buf,';')) != NULL)
ind.mydate = mydate(cp+2);
header = 1;
pos = ftell(fp);
/* While in the SMTP header, set index fields */
while(bgets(buf,sizeof(buf),fp) != NULLCHAR ) {
if(*buf == '\0')
break;
set_index(buf,&ind);
}
}
pos = ftell(fp);
}
if(ferror(fp)) {
default_index("",&ind);
fclose(fp);
close(idx);
return ERROR;
}
if(previous) {
ind.size = pos - start;
if(verbose)
print_index(&ind);
if(WriteIndex(idx,&ind) == -1) {/* Write index for previous message */
default_index("",&ind);
fclose(fp);
close(idx);
return ERROR;
}
}
default_index("",&ind);
fclose(fp);
close(idx);
return 0;
}
/* Update the index file */
int write_index(char *name, struct mailindex *ind) {
int idx, err;
struct indexhdr hdr;
char buf[FILE_PATH_SIZE];
sprintf(buf,"%s/%s.ind",Mailspool,name);
if((idx=open(buf,READWRITEBINARY)) == -1) {
/* Index file doesn't exist, create it */
if((idx=open(buf,CREATETRUNCATEBINARY,CREATEMODE)) != -1){
default_header(&hdr);
if (write_header(idx,&hdr) == -1) return -1;
} else
return -1;
}
lseek(idx,0,SEEK_END);
err=WriteIndex(idx,ind);
close(idx);
return err;
}
void delete_index(char *filename) {
char idxfile[FILE_PATH_SIZE];
sprintf(idxfile,"%s/%s.ind",Mailspool,filename);
unlink(idxfile);
}
int write_header(int idx,struct indexhdr *hdr) {
lseek(idx,0,SEEK_SET);
hdr->version = INDEXVERSION;
return (write(idx,hdr,sizeof(struct indexhdr)) == sizeof(struct indexhdr) ? 0 : -1);
}
int read_header(int idx,struct indexhdr *hdr) {
int val;
lseek(idx,0,SEEK_SET);
val = read(idx,hdr,sizeof(struct indexhdr));
if(val != sizeof(struct indexhdr) || hdr->version != INDEXVERSION)
return -1;
return 0;
}
/* Read an index from the index file. Assumes the file is opened
* for binary reads, and that the filepointer is pointing to the
* start of the message to read...
* Returns 0 if valid, -1 if error
*/
int read_index(int idx,struct mailindex *ind) {
int len;
char *buf,*curr;
struct cclist *newcc;
struct fwdbbs *newbbs;
/* Get the size of this index */
if(read(idx,&len,sizeof(len)) != sizeof(len))
return -1;
/* Now read the index */
if((buf = mallocw(len)) == NULL)
return -1;
if(read(idx,buf,len) != len) {
free(buf);
return -1;
}
/* And copy all elements to the index */
curr = buf;
/* Get the message id */
ind->msgid = *(long *)curr;
curr += sizeof(ind->msgid);
ind->type = *curr++;
ind->status = *curr++;
ind->size = *(long*)curr;
curr += sizeof(ind->size);
ind->to = strdup(curr);
curr += strlen(curr) + 1;
ind->from = strdup(curr);
curr += strlen(curr) + 1;
ind->subject = strdup(curr);
curr += strlen(curr) + 1;
ind->replyto = strdup(curr);
curr += strlen(curr) + 1;
ind->messageid = strdup(curr);
curr += strlen(curr) + 1;
ind->mydate = *(long *)curr;
curr += sizeof(ind->mydate);
ind->date = *(long *)curr;
curr += sizeof(ind->date);
while(*curr) {
newcc = mallocw(sizeof(struct cclist));
newcc->to = strdup(curr);
newcc->next = ind->cclist;
ind->cclist = newcc;
curr += strlen(curr) + 1;
}
curr++;
while(*curr) {
newbbs = mallocw(sizeof(struct fwdbbs));
strcpy(newbbs->call,curr);
newbbs->next = ind->bbslist;
ind->bbslist = newbbs;
curr += strlen(curr) + 1;
}
free(buf);
return 0;
};
void print_index(struct mailindex *ind) {
struct fwdbbs *bbs;
struct cclist *cc;
tprintf("\nSize %ld, ID %ld, flags: %c%c%c\n",ind->size,ind->msgid,ind->type,
ind->status & BM_READ ? 'R' : 'N',ind->status & BM_HOLD ? 'H' : ' ');
tprintf("To: %s\n",ind->to);
tprintf("Cc:");
for(cc=ind->cclist;cc;cc=cc->next)
tprintf(" %s",cc->to);
tputc('\n');
tprintf("From: %s\n",ind->from);
tprintf("Received: %s",ctime(&ind->mydate));
tprintf("Reply-to: %s\n",ind->replyto ? ind->replyto : "");
tprintf("Subject: %s\n",ind->subject);
tprintf("Message-Id: %s\n",ind->messageid);
tprintf("Date: %s",ctime(&ind->date));
tprintf("X-Forwarded-To:");
for(bbs=ind->bbslist;bbs;bbs=bbs->next)
tprintf(" %s",bbs->call);
tputc('\n');
tputc('\n');
}
void dotformat(char *area) {
while(*area) {
if(*area == '\\' || *area == '/')
*area = '.';
area++;
}
}
void dirformat(char *area) {
while(*area) {
if(*area == '\\' || *area == '.')
*area = '/';
area++;
}
}
void firsttoken(char *line) {
while(*line) {
if(*line == ' ' || *line == '\n' || *line == '\t') {
*line = '\0';
break;
}
line++;
}
}
/* Returns 1 if name is a public message Area, 0 otherwise */
int
isarea(name)
char *name;
{
FILE *fp;
char *cp, *area;
char buf[LINELEN];
if((fp = fopen(Arealist,READ_TEXT)) == NULLFILE)
return 0;
area = strdup(name);
dotformat(area);
while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
/* The first word on each line is all that matters */
firsttoken(buf);
dotformat(buf);
if(stricmp(area,buf) == 0) { /* found it */
fclose(fp);
free(area);
return 1;
}
}
fclose(fp);
free(area);
return 0;
}
/* Get a line from the text file that was opened in binary mode.
* Delete the CR/LF at the end !
*/
char *bgets(char * buf,int size,FILE *fp) {
char *cp;
if(fgets(buf,size,fp) == NULL)
return NULL;
cp = buf;
while(*cp) {
if(*cp == 0xd || *cp == 0xa)
*cp = '\0';
cp++;
}
return buf;
}
#ifdef notdef
void readareas __ARGS((char *name,char *mpath));
int is_area __ARGS((char *name));
int isarea;
struct areas {
struct areas *next;
char *name;
};
struct areas *Areas = NULL;
void readareas(char *name,char *mpath) {
FILE *fp;
struct areas *ca,*na;
char *cp,mp[FILE_PATH_SIZE],buf[FILE_PATH_SIZE];
if((fp=fopen(name,READ_TEXT)) == NULL)
return;
while(fgets(buf,sizeof(buf),fp) != NULL) {
if(buf[0] == '#') /* comment line */
continue;
cp = buf;
/* get first token on line */
while(*cp) {
if(*cp == '\n' || *cp == ' ' || *cp == '\t') {
*cp = '\0';
break;
}
cp++;
}
if(buf[0] != '\0') {
cp = buf;
while(*cp) {
if(*cp == '.' || *cp == '\\')
*cp = '/';
cp++;
}
sprintf(mp,"%s/%s.txt",mpath,buf);
na = malloc(sizeof(struct areas));
na->name = strdup(mp);
na->next = NULL;
if(Areas == NULL) {
Areas = na;
} else {
ca->next = na;
}
ca = na;
}
}
fclose(fp);
}
int is_area(char *name) {
struct areas *a;
a = Areas;
while(a) {
if(stricmp(a->name,name) == 0)
return 1;
a = a->next;
}
return 0;
}
void showareas() {
struct areas *a;
a = Areas;
while(a) {
tprintf("%s\n",a->name);
a = a->next;
}
}
#endif
#ifndef MAIL2IND
void UpdateIndex(char *path,int force) {
char *wildcard,*newpath,*fullname;
struct ffblk ff,iff;
int done;
if((wildcard = malloc(129)) == NULL) {
return;
}
if((newpath = malloc(129)) == NULL) {
free(wildcard);
return;
}
if((fullname = malloc(129)) == NULL) {
free(wildcard);
free(newpath);
return;
}
/* First check all the files */
if(!path)
sprintf(wildcard,"%s/*.txt",Mailspool);
else
sprintf(wildcard,"%s/%s/*.txt",Mailspool,path);
done = findfirst(wildcard,&ff,0);
while(!done){
if(!path)
strcpy(fullname,ff.ff_name);
else
sprintf(fullname,"%s/%s",path,ff.ff_name);
/* get rid of extension */
*(fullname+strlen(fullname)-4) = '\0';
if(force) {
/* Attempt to lock the mail file! */
if(!mlock(Mailspool,fullname)) {
IndexFile(fullname,0);
rmlock(Mailspool,fullname);
}
} else {
/* Now find the index file */
sprintf(wildcard,"%s/%s",Mailspool,fullname);
strcat(wildcard,".IND");
/* If there is no index, or the index is older then the text file.
* Go create a new index file !
*/
if( findfirst(wildcard,&iff,0) != 0 ||
(ff.ff_fdate > iff.ff_fdate) ||
((ff.ff_fdate == iff.ff_fdate) && ff.ff_ftime > iff.ff_ftime)
) {
/* Attempt to lock the mail file! */
if(!mlock(Mailspool,fullname)) {
IndexFile(fullname,0);
rmlock(Mailspool,fullname);
}
}
}
done = findnext(&ff);
}
/* Now check for sub-directories */
if(!path)
sprintf(wildcard,"%s/*.*",Mailspool);
else
sprintf(wildcard,"%s/%s/*.*",Mailspool,path);
done = findfirst(wildcard,&ff,FA_DIREC);
while(!done){
if(strcmp(ff.ff_name,".") && strcmp(ff.ff_name,"..")) {
/* Not the present or 'mother' directory, so create new path,
* and recurs into it.
*/
if(!path)
strcpy(newpath,ff.ff_name);
else
sprintf(newpath,"%s/%s",path,ff.ff_name);
UpdateIndex(newpath,force);
}
done = findnext(&ff);
}
free(wildcard);
free(newpath);
free(fullname);
return;
}
/* Make sure the index file associated with the mailbox 'name' is current.
* The mailbox should be locked before calling SyncIndex.
* Parameters:
* char *name should be the area filename, without ending '.txt' !
* Eg: 'johan'
* Returns:
* NOERROR (== 0) if index was current, or has been made current.
* others if unable to update the index file.
*/
int SyncIndex(char *name)
{
int mail,ind;
struct ffblk mff,iff;
char *area;
char buf[129];
area = strdup(name); /* ensure mbox name is in dir format */
dirformat(area);
/* Check the index file */
sprintf(buf,"%s/%s.txt",Mailspool,area);
mail = findfirst(buf,&mff,0);
sprintf(buf,"%s/%s.ind",Mailspool,area);
ind = findfirst(buf,&iff,0);
if(mail != 0 && ind == 0) {
ind=unlink(buf); /* remove index file if mbox nonexistent */
}
else if((mail == 0 && ind != 0) ||
(mff.ff_fdate > iff.ff_fdate) ||
((mff.ff_fdate == iff.ff_fdate) && mff.ff_ftime > iff.ff_ftime)
) {
ind=IndexFile(area,0);
}
else ind=NOERROR;
free(area);
return(ind);
}
#endif /* MAIL2IND */